//跟踪内存泄露
#ifndef __TRACE_MEMORY_LEAK_H
#define __TRACE_MEMORY_LEAK_H


#include <list>
#include<string>
#include <iostream>
#ifdef _DEBUG

inline void * __cdecl operator new(unsigned int size, const char *file, int line);


#endif
#ifdef _DEBUG

#define DEBUG_NEW new(__FILE__, __LINE__)

#else

#define DEBUG_NEW new

#endif

#ifdef _DEBUG
typedef int DWORD;

typedef struct

{

	DWORD address;

	DWORD size;

	char file[64];

	DWORD line;

}ALLOC_INFO;

 
std::list<int> ll;
typedef std::list<ALLOC_INFO *> AllocList;
AllocList *  allocList;

 void AddTrack(DWORD addr, DWORD asize, const char *fname, DWORD lnum)

{

	ALLOC_INFO *info;

	if(!allocList)

	{

	allocList = new(AllocList);

	}

	info = new(ALLOC_INFO);

	info->address = addr;

	strncpy(info->file, fname, 63);

	info->line = lnum;

	info->size = asize;
	allocList->insert(allocList->begin(), info);

};

 

void RemoveTrack(DWORD addr)

{

	AllocList::iterator i;

	if(!allocList) return;

	for(i = allocList->begin(); i != allocList->end(); i++)

	{

		if((*i)->address == addr)

		{

			allocList->remove((*i));

			break;

		}

	}

};


inline void * __cdecl operator new(unsigned int size, const char *file, int line)

{
	void *ptr = (void *)malloc(size);
	AddTrack((DWORD)ptr, size, file, line);
	return(ptr);

};

inline void __cdecl operator delete(void *p)

{

	RemoveTrack((DWORD)p);

	free(p);

};
void OutputDebugString(char * str){
	std::cout<<str<<std::endl;
}

void DumpUnfreed()
{
	AllocList::iterator i;

	DWORD totalSize = 0;

	char buf[1024];

	if(!allocList) return;

	for(i = allocList->begin(); i != allocList->end(); i++)

	{

		sprintf(buf, "\"%-10s: LINE %d, ADDRESS %d %d unfreed \"", (*i)->file, (*i)->line, (*i)->address, (*i)->size); OutputDebugString(buf);

		totalSize += (*i)->size; 
	} 
	sprintf(buf, "\"----------------------------------------------------------- \"");

	OutputDebugString(buf);

	sprintf(buf, "\"Total Unfreed: %d bytes \"", totalSize);

	OutputDebugString(buf);

}


#endif
#endif // !__TRACE_MEMORY_LEAK_H
